package com.tiankun.eurekauserinfo.service.impl;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.tiankun.eurekauserinfo.config.PayConfig;
import com.tiankun.eurekauserinfo.exception.BusinessException;
import com.tiankun.eurekauserinfo.mapper.OrderGoodsMapper;
import com.tiankun.eurekauserinfo.mapper.OrderMapper;
import com.tiankun.eurekauserinfo.pojo.Order;
import com.tiankun.eurekauserinfo.pojo.OrderGoods;
import com.tiankun.eurekauserinfo.service.OrderService;
import com.tiankun.eurekauserinfo.utils.RandomNumber;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA
 * User: bear
 * Date: 2020/11/13
 * Description
 * Version: V1.0
 */
@Service(value = "orderService")
@Transactional
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper = null;
    @Resource
    private OrderGoodsMapper orderGoodsMapper = null;
    @Resource
    private RedisTemplate redisTemplate = null;


    @Override
    public String addOrder(String userPhone, List<Map<String, Object>> godDetails) {
        Order order = new Order();
        OrderGoods orderGoods = new OrderGoods();
        //获得订单的基本信息（产生订单的时候，不需要有优惠券信息，优惠券信息在支付的时候传入）
        order.setUserPhone(userPhone);
        //产生订单号
        String orderRandom = RandomNumber.randomNumber();
        Integer totalPrice = 0;
        //遍历循环
        for (Map<String, Object> godDetail : godDetails) {
            orderGoods.setId(null);
            Integer money = (Integer) godDetail.get("money");
            orderGoods.setGoodsId((Integer) godDetail.get("godId"));
            Integer godNumber = (Integer) godDetail.get("godNumber");
            HashOperations hashOperations = redisTemplate.opsForHash();

            orderGoods.setGod_state(0);
            orderGoods.setGodNumber(godNumber);
            //计算出单间物品金额和数量相对应的应付金额
            Integer price = money * godNumber;
            //循环遍历累加总支付金额
            totalPrice = totalPrice + price;
            //加入生成的订单号
            orderGoods.setOrderRandom(orderRandom);
            //添加商品详情到数据库
            orderGoodsMapper.insertSelective(orderGoods);
        }
        //产生订单时，状态默认为未付款
        order.setState(0);
        //交易总金额
        order.setMoney(totalPrice);
        //添加订单号
        order.setOrderRandom(orderRandom);
        //创建订单之前，需要删除掉购物车当中这个商品的信息
//        redisTemplate.opsForHash()
        orderMapper.insertSelective(order);

        return orderRandom;
    }

    @Override
    public String payment(String userPhone, Integer tktMoney, String orderRandom, Integer ticketId) {

        //实例化客户端（参数：网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型），为了取得预付订单信息
        AlipayClient alipayClient = new DefaultAlipayClient(PayConfig.URL, PayConfig.APP_ID,
                PayConfig.APP_PRIVATE_KEY, PayConfig.FORMAT, PayConfig.CHARSET, PayConfig.ALIPAY_PUBLIC_KEY,
                PayConfig.SIGN_TYPE);

        //实例化具体API对应的request类
        AlipayTradePagePayRequest payRequest = new AlipayTradePagePayRequest();
        payRequest.setNotifyUrl(PayConfig.notifyUrl);
        payRequest.setReturnUrl(PayConfig.returnUrl);


        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式
        AlipayTradePagePayModel payModel = new AlipayTradePagePayModel();
        //交易订单号
        payModel.setOutTradeNo(orderRandom);
        //对一笔交易的具体描述信息。这里存储用户电话
        payModel.setBody(userPhone);
        //交易超时时间 这里的30m就是30分钟
        payModel.setTimeoutExpress("30m");
        //1.获取订单应付金额
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("orderRandom", orderRandom);
        Order order = orderMapper.selectOneByExample(example);
        if (order == null) {
            throw new BusinessException("订单不存在，请查证后再试");
        }
        Integer money = order.getMoney();
        //2.实付金额=应付金额-优惠额度
        money = money - tktMoney;
        //
        //支付金额 后面保留2位小数点..不能超过2位(但是本项目将金额控制为整数)
        System.out.println(money);
        payModel.setTotalAmount(String.valueOf(money));
        // //电脑网站支付销售产品码，不同的支付方式productCode不同 销售产品码（固定值）
//        payModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        payRequest.setBizModel(payModel);
        try {
            // 这里和普通的接口调用不同，使用的是sdkExecute
            //返回支付宝订单信息(预处理)
            AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(payRequest);
            //就是orderString 可以直接给APP请求，无需再做处理。
            String result = alipayTradePagePayResponse.getBody();
            if (ticketId != null) {

                //获取操作符
                HashOperations hashOperations = redisTemplate.opsForHash();
                //将ticketId和userPhone存入redis
                hashOperations.put("tkt" + orderRandom, "tktId", ticketId);
                hashOperations.put("tkt" + orderRandom, "userPhone", userPhone);
                Object ticketIds = hashOperations.get("tkt" + orderRandom, "tktId");
                Object userPhone1 = hashOperations.get("tkt" + orderRandom, "userPhone");
                //设置键过期时间，跟支付时间一致
                redisTemplate.expire("tkt" + orderRandom, 30, TimeUnit.MINUTES);
                ValueOperations valueOperations = redisTemplate.opsForValue();
            }

            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public Order findByOrderId(String orderRandom) {
        Order orders = new Order();
//        order.setId(OrderId);
        orders.setOrderRandom(orderRandom);
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("orderRandom", orderRandom);
        //通过订单号查询订单详情
        Order order = orderMapper.selectOneByExample(example);
        Example goodsExample = new Example(OrderGoods.class);
        //通过订单号查询订单商品详情
        goodsExample.createCriteria().andEqualTo("orderRandom", orderRandom);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(goodsExample);
        order.setGoods(orderGoods);
        return order;
    }

    @Override
    public List<Order> findByUserPhone(String userPhone) {
        if (userPhone == null) {
            throw new BusinessException("请传入正确的电话号码");
        }
        Example example = new Example(Order.class);
        //以userPhone作为查询条件
        example.createCriteria().andEqualTo("userPhone", userPhone);
        //查询所有的order
        return orderMapper.selectByExample(example);
    }

    @Override
    public Map<String, Object> alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {

        Order order = new Order();
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, PayConfig.ALIPAY_PUBLIC_KEY, PayConfig.CHARSET, PayConfig.SIGN_TYPE); //调用SDK验证签名

        if (signVerified) {
            //交易订单号
            String orderRandom = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //获取操作符
            HashOperations hashOperations = redisTemplate.opsForHash();
            Set keys = hashOperations.keys("tkt" + orderRandom);
            if (keys.size() == 0) {
                return null;
            } else {

                Integer ticketIds = (Integer) hashOperations.get("tkt" + orderRandom, "tktId");
                String userPhone1 = (String) hashOperations.get("tkt" + orderRandom, "userPhone");
                //根据订单号来改变该订单的状态
                //1代表已支付
                order.setState(1);
                order.setTicketId(ticketIds);
                Example example = new Example(order.getClass());
                example.createCriteria().andEqualTo("orderRandom", orderRandom);
                //根据订单号来修改订单的状态
                orderMapper.updateByExampleSelective(order, example);
                Map<String, Object> map = new HashMap<>();
                map.put("tktId", ticketIds);
                map.put("userPhone", userPhone1);
                return map;
            }
        }
        return null;
    }

    @Override
    public Integer confirmReceipt(Integer orderId) {
        Order order = new Order();
        order.setState(2);
        order.setId(orderId);
        return orderMapper.updateByPrimaryKeySelective(order);

    }
}
